/*!
 * \file iegenlib_context_test.cc
 *
 * \brief IEGenLib context tests
 *
 * This file is to test the IEGenLibContext class.
 *
 * \date Started: 12/20/10
 * \date Last Modified: 12/20/10
 * \authors Alan LaMielle
 */

#include <iegenlib/iegenlib.h>

using std::make_pair;

#include <gtest/gtest.h>

using iegenlib::StringException;
using iegenlib::IEGenLibContext;
using iegenlib::Symbolic;

TEST(IEGenLibContextTest,SimplifyConjunctions){
   IEGenLibContext context;

   EXPECT_EQ(context.getSimplifyConjunctions(),true);

   context.setSimplifyConjunctions(false);

   EXPECT_EQ(context.getSimplifyConjunctions(),false);
}

TEST(IEGenLibContextTest,Equality){
   IEGenLibContext context1,context2;
   EXPECT_EQ(context1,context2);

   context1.setSimplifyConjunctions(false);
   EXPECT_NE(context1,context2);
   context2.setSimplifyConjunctions(false);
   EXPECT_EQ(context1,context2);

   context1.addSymbolic(Symbolic("n"));
   EXPECT_NE(context1,context2);
   context2.addSymbolic(Symbolic("n"));
   EXPECT_EQ(context1,context2);

   context1.addInversePair("f","f_inv");
   EXPECT_NE(context1,context2);
   context2.addInversePair("f","f_inv");
   EXPECT_EQ(context1,context2);
}

TEST(IEGenLibContextTest,Symbolics){
   IEGenLibContext context;

   EXPECT_EQ(context.getSymbolics(),set<Symbolic>());

   set<Symbolic> syms;
   syms.insert(Symbolic("n"));
   context.addSymbolic(Symbolic("n"));

   EXPECT_EQ(context.getSymbolics(),syms);

   syms.insert(Symbolic("m"));
   syms.insert(Symbolic("q"));

   context.addSymbolic(Symbolic("m"));
   context.addSymbolic(Symbolic("q"));

   EXPECT_EQ(context.getSymbolics(),syms);
}

TEST(IEGenLibContextTest,SymbolicNames){
   IEGenLibContext context;

   EXPECT_EQ(context.getSymbolicNames(),set<string>());

   set<string> syms;
   syms.insert("n");
   context.addSymbolic(Symbolic("n"));

   EXPECT_EQ(context.getSymbolicNames(),syms);

   syms.insert("m");
   syms.insert("q");

   context.addSymbolic(Symbolic("m"));
   context.addSymbolic(Symbolic("q"));

   EXPECT_EQ(context.getSymbolicNames(),syms);
}

TEST(IEGenLibContextTest,InverseFunctionPairsBasic){
  IEGenLibContext context;
  bool res;
  string inverse_name;

  EXPECT_FALSE(context.hasInverse("f",inverse_name));
  context.addInversePair("f","f_inv");

  set<pair<string,string> > pairs;
  pairs.insert(make_pair("f","f_inv"));

  EXPECT_EQ(pairs,context.getInversePairs());
  res=false;
  inverse_name="blargh";
  res=context.hasInverse("f",inverse_name);
  EXPECT_TRUE(res);
  EXPECT_EQ("f_inv",inverse_name);
  res=false;
  inverse_name="blargh";
  res=context.hasInverse("f_inv",inverse_name);
  EXPECT_TRUE(res);
  EXPECT_EQ("f",inverse_name);

  context.addInversePair("g","g_inv");
  pairs.insert(make_pair("g","g_inv"));

  EXPECT_EQ(pairs,context.getInversePairs());
  res=false;
  inverse_name="blargh";
  res=context.hasInverse("g",inverse_name);
  EXPECT_TRUE(res);
  EXPECT_EQ("g_inv",inverse_name);
  res=false;
  inverse_name="blargh";
  res=context.hasInverse("g_inv",inverse_name);
  EXPECT_TRUE(res);
  EXPECT_EQ("g",inverse_name);
}

TEST(IEGenLibContextTest,InverseFunctionPairsTricky){
  IEGenLibContext context;
  bool fail;

  //Empty function name string
  fail=true;
  try{context.addInversePair("","a");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}
  fail=true;
  try{context.addInversePair("a","");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}
  fail=true;
  try{context.addInversePair("","");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}

  //Same function name strings
  fail=true;
  try{context.addInversePair("f","f");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}

  //Adding same pair a second time
  context.addInversePair("f","f_inv");
  fail=true;
  try{context.addInversePair("f","f_inv");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}
  fail=true;
  try{context.addInversePair("f_inv","f");}
  catch(StringException e){fail=false;}
  if(fail){ASSERT_TRUE(false);}
}
